package coupon

import (
	"time"
)

type Coupon struct {
	ID          string    // 优惠券ID
	Type        string    // "percentage" 或 "amount"
	Discount    float64   // 百分比折扣（0-1）或金额折扣
	ValidFrom   time.Time // 有效开始日期
	ValidUntil  time.Time // 有效结束日期
	MinSpend    float64   // 使用优惠券所需的最低消费金额
	MaxDiscount float64   // 百分比优惠券的最大折扣金额
	CouponType  int       // 1 表示兑换券，2 表示折扣券，3 表示消费券
}

type CouponManager struct {
	Coupons []Coupon
}

func NewCouponManager(coupons []Coupon) *CouponManager {
	return &CouponManager{Coupons: coupons}
}

// isCouponValid 检查优惠券是否在有效期内且满足最低消费金额
func (cm *CouponManager) isCouponValid(coupon Coupon, currentAmount float64, currentTime time.Time) bool {
	return currentTime.After(coupon.ValidFrom) && currentTime.Before(coupon.ValidUntil) && currentAmount >= coupon.MinSpend
}

// calculateDiscount 计算优惠后的金额
func (cm *CouponManager) calculateDiscount(coupon Coupon, originalAmount float64) float64 {
	if coupon.Type == "percentage" {
		discountedAmount := originalAmount * (1 - coupon.Discount)
		if discountedAmount < originalAmount-coupon.MaxDiscount {
			return originalAmount - coupon.MaxDiscount
		}
		return discountedAmount
	}
	return originalAmount - coupon.Discount
}

// selectBestCombination 从优惠券列表中选择最优优惠券组合
func (cm *CouponManager) selectBestCombination(currentAmount float64, currentTime time.Time, maxDiscountRatio float64) ([]*Coupon, float64) {
	var bestCoupons []*Coupon
	bestDiscountedAmount := currentAmount

	// 检查是否有有效的兑换券
	for _, exchangeCoupon := range cm.Coupons {
		if exchangeCoupon.CouponType == 1 && cm.isCouponValid(exchangeCoupon, currentAmount, currentTime) {
			return []*Coupon{&exchangeCoupon}, currentAmount // 兑换券直接使用，优惠后的金额为初始价格
		}
	}

	// 检查单个优惠券
	for _, coupon := range cm.Coupons {
		if cm.isCouponValid(coupon, currentAmount, currentTime) {
			discountedAmount := cm.calculateDiscount(coupon, currentAmount)
			if discountedAmount < bestDiscountedAmount && discountedAmount >= 0 {
				bestDiscountedAmount = discountedAmount
				bestCoupons = []*Coupon{&coupon}
			}
		}
	}

	// 检查组合使用的情况
	for _, coupon1 := range cm.Coupons {
		for _, coupon2 := range cm.Coupons {
			if coupon1.CouponType != coupon2.CouponType && cm.isCouponValid(coupon1, currentAmount, currentTime) && cm.isCouponValid(coupon2, currentAmount, currentTime) {
				discountedAmount := cm.calculateDiscount(coupon1, currentAmount)
				discountedAmount = cm.calculateDiscount(coupon2, discountedAmount)
				if discountedAmount < bestDiscountedAmount && discountedAmount >= 0 {
					discount := currentAmount - discountedAmount
					if maxDiscountRatio == 0 || discount <= currentAmount*maxDiscountRatio {
						bestDiscountedAmount = discountedAmount
						bestCoupons = []*Coupon{&coupon1, &coupon2}
					}
				}
			}
		}
	}

	if bestDiscountedAmount < 0 {
		return nil, currentAmount
	}

	return bestCoupons, bestDiscountedAmount
}
